home *** CD-ROM | disk | FTP | other *** search
- /*
- * SAMIGA.C - 19th Aug 1988 - System dependent functions for the
- * single-user SYSOP version of 'mb'.
- * Pete Hardie VE5VA
- *
- */
-
- #include "mb.h"
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/text.h>
- #include <ctype.h>
- #include <time.h>
- #include "rexxhostbase.h"
-
- extern struct RexxHost *rexx_host;
- extern long rexxbit;
- char arexx_port_name[50];
- char *arexx_port = 0L;
-
-
- extern struct Window *mywindow;
- extern struct IntuiMessage *NewMessage;
- short debug;
- char tmpstr[300];
- extern struct IOStdReq *Con_Read,*Con_Write;
- extern char optflags[];
-
-
- char l_date[7], l_time[5];
- char z_date[7], z_time[5];
- char pt_flag = 0;
- short done_flag = 1;
- /*
- * Set the current I/O device.
- */
-
- ioport(pp)
- PORTS *pp;
- {
- port = pp;
- }
-
- /*
- * Return non-zero if a character waits at current input.
- */
-
- instat()
- {
- register int st;
-
- /* check for char at console */
- if(CheckIO((struct IORequest *)Con_Read))return(1);
- return(0);
- }
-
- /*
- * Put the character out the current port,
- * echo to console if the current port is not the console.
- * Note special handling of end-of-line character.
- */
-
- outchar(ch)
- char ch;
- {
- if (ch is '\r') return;
- if (ch is '\n') ch = '\r';
- /*
- * Put it out to the console, if it is going there.
- */
-
- if ((port->dev is p_console) or port->ec) {
- if (ch is '\r') ttputc('\n');/* output '\n' */;
- ttputc(ch);
- }
- }
- #define PROCLEN 200
- unsigned char procstr[PROCLEN];
- outstr(cp)
- unsigned char *cp;
- {
- register unsigned char *p,*q;
- register int beepcount;
- if(debug) {
- p = cp;
- while(*p)outchar(*p++);
- return;
- }
- if(arexx_port) {
- remnl(cp);
- if(debug)printf("Send '%s' to '%s'\n",cp,arexx_port);
- SendRexxMsg((STRPTR)arexx_port,0L,(STRPTR)cp,0L);
- return;
- }
- /* count the number of beeps in the line so that we can give an audible
- as well as visual beep
- */
- if((port->dev is p_console) || port->ec) {
- beepcount = 0;
- for(q = cp,p = &procstr[0];*q && p < &procstr[PROCLEN-1];q++) {
- if(*q is '\r')continue;
- *p++ = *q;
- if(*q == '\007')beepcount++;
- }
- *p = 0;
- Con_Write->io_Data = (APTR) &procstr[0];
- Con_Write->io_Length = p-&procstr[0];
- Con_Write->io_Command = CMD_WRITE;
- DoIO((struct IORequest *)Con_Write);
- while(beepcount--) {
- beep();
- Delay(15L);
- }
- }
- }
- /* samiga can't talk to the tnc! */
- PORTS *devtnc = 0L;
- char *inittnc(infile)
- char *infile;
- {
- return((char *)0);
- }
- /*
- hex(c)
- char c;
- {
- register char k;
- k = c;
- if((k >= '0') && (k <= '9'))return(k - '0');
- k = toupper(k);
- if((k >= 'A') && (k <= 'F'))return(k - 'A' + 10);
- return(0);
- }
- */
- flipdebug()
- {
- debug ^= 1;
- if(debug) {
- ttputs("debug now ON\n");
- }
- else {
- ttputs("debug now OFF\n");
- }
- }
- extern unsigned char ichar;
- extern long keybit,windbit,timerbit;
- long getbits;
- struct timeRequest {
- struct IORequest tr_node;
- struct timeval tr_time;
- };
- extern struct timeRequest timermsg;
-
- /* replace the original do_idle because it busy-waited ...
- this version sleeps until there is something to do
- */
- extern short cursecs;
- do_idle()
- {
- register unsigned char ch,*q;
- register PORTS *p;
- int curmin,curmon;
- ULONG class,waitbits;
- char go_flag;
- USHORT code;
- struct RexxMsg *rexxmessage; /* incoming rexx messages */
- STRPTR Arg; /* Temporary string pointer */
-
- arexx_port = 0L;
- cursor_off();
- for(p=porthd; p != NULL; p = p->next) {
- p->ec = p->ecmon;
- }
- ioport(cport);
- /* figure out time to next forward and set timer */
- curtim();
- curmin = 60 - cursecs;
- settimer(curmin);
- /* There might already be an unread char at the serial or console port */
- clrbusy();
- waitbits = windbit | timerbit | keybit | rexxbit;
- ttputs("\nIDLE\n");
- while(1) {
- getbits = Wait(waitbits);
- go_flag = 0;
- /* Although SYSOP has an AREXX port open it does not take commands
- from other AREXX ports. It only gives them
- */
- if(rexxbit & getbits) {
- while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
- if(Arg = GetRexxCommand(rexxmessage)) {
- if(!strncmp((char *)Arg,"GO",2)) {
- go_flag++;
- q = (unsigned char *)Arg + 2;
- while((*q == ' ') || (*q == '\n'))q++;
- if(*q) {
- strcpy(arexx_port_name,(char *)q);
- arexx_port = arexx_port_name;
- }
- else {
- arexx_port = 0L;
- }
- }
- ReplyRexxCommand(rexxmessage,0L,0L,0L);
- if(go_flag)goto cmd_exit;
- }
- else {
- FreeRexxCommand(rexxmessage);
- }
- }
- }
- if(windbit & getbits) {
- while(NewMessage =
- (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
- /* Need this to cancel out the clrbusy in done() */
- setbusy();
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == wchar) {
- cmd_exit:
- ioport(cport);
- cursor_on();
- /* could have a timerbit set here.
- readbit could also be set but must handle that a
- different way.
- */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- return;
- }
- if(ch == '\033') {
- ttputs("do_idle\n");
- }
- }
- /* This code is deliberately placed last. If a timer bit occurs
- at the same time as a character arrives from the serial port
- then this code will hang the serial port up because afwd()
- tries to use the port again without clearing the existing char.
- So workaround it. Putting the timer code here guarantees that
- even if the ser char did occur it will be handled first and the
- ser char code handles the problem of returning from this routine
- with a timer bit set.
- */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- curtim();
- curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
- curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
- settimer(60);
- }
- }
- }
- /* replace getdat from mbutil to reduce busy waits */
- /* MAXLEN is the longest unterminated line the justification routine
- will accept before it rips out the word and keeps it for later use.
- MAXJUST is the longest word that the routine will keep ... if the word
- is any longer than this then it will just allow you to mess up the line!
- */
- #define MAXLEN 77
- #define MAXJUST 20
- unsigned char x_pos = 0; /* Position on line for right justification */
- unsigned char s_pos = 0; /* Position of last space on the line */
- char saveword[MAXJUST+2];
- char *cp;
- getdat()
- {
-
- register char ch;
- register PORTS *p;
- register char *q;
- int eflag;
- int curmin;
- ULONG class,waitbits;
- USHORT code;
- struct RexxMsg *rexxmessage; /* incoming rexx messages */
- STRPTR Arg;
-
- x_pos = s_pos = 0;
- p = port;
- cp = p->line;
- *cp = 0;
- /* If there was a justified word left over from previous line .. put it
- in here now.
- */
- if(*saveword) {
- q = saveword;
- while(*q) {
- ttputc(*q);
- *cp++ = *q++;
- x_pos++;
- }
- }
- *saveword = 0;
- /* Is a timeout timer required? */
- curmin = 0;
- if(p->flags & p_dotmr) {
- curmin = p->ctime;
- }
- if(curmin)settimer(curmin); /* set timeout timer if required */
- p->flags setbit p_dotmr;
-
- waitbits = windbit | timerbit | keybit | rexxbit;
- while(1) {
- getbits = Wait(waitbits);
- if(windbit & getbits) {
- while(NewMessage =
- (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
- done(1);
- }
- }
- }
- }
- if(rexxbit & getbits) {
- while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
- if(Arg = GetRexxCommand(rexxmessage)) {
- strcpy(p->line,(char *)Arg);
- strcat(p->line,"\n");
- ReplyRexxCommand(rexxmessage,0L,0L,0L);
- goto cmd_exit;
- }
- else {
- FreeRexxCommand(rexxmessage);
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == '\033') {
- if(p == cport)ttputs("getdatCON\n");
- else ttputs("getdatTNC\n");
- }
- if(charf(ch)) {
- cmd_exit:
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- if(curmin)cantimer();
- }
- return(true);
- }
- }
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- *cp = 0;
- if(!(p->mode & idle))p->mode = timeout;
- return (true);
- }
- }
- }
- charf(s)
- unsigned char s;
- {
- register unsigned char ch;
- register char *q,*r;
- register int i;
- PORTS *p;
-
- p = port;
- ch = s;
- /* Ignore characters with high order bit set...they tie up the TNC */
- if(ch > 0177)return(0);
- *cp = ch;
- if((cp == p->line + linelen - 2) || (ch == '\r')) {
- do_lf:
- if(ch == '\r')*cp = '\n';
- *++cp = 0;
- if(p->flags & p_echo)outchar('\n');
- return(1);
- }
- if((ch >= ' ') && (ch <= 0176)) {
- /*
- Do justification for local user.
- */
- if(p->dev == p_console) {
- if(ch == ' ') {
- s_pos = x_pos;
- /* If the space is at exactly the point we would have justified
- the line then fake a CR anyway
- */
- if(x_pos == MAXLEN) {
- ch = '\r';
- *saveword = 0;
- goto do_lf;
- }
- }
- else {
- /* It's not a space ... should we do the justify?
- */
- if(x_pos == MAXLEN) {
- /* This word can't be longer than MAXJUST or we just leave
- it alone and let them mess up the line
- */
- if((i = (MAXLEN - s_pos)) < MAXJUST) {
- q = saveword;
- r = &p->line[s_pos+1];
- do {
- *q++ = *r++;
- ttputs("\b \b");
- }while(--i);
- *q = 0;
- cp = &p->line[s_pos];
- ch = '\r';
- goto do_lf;
- }
- }
- }
- }
- x_pos++;
- if (p->flags & p_echo) ttputc(ch);
- cp++;
- return(0);
- }
- switch(ch) {
- default:
- break;
- case 26: /* Control - Z */
- cp++;
- x_pos++;
- break;
- case '\t':
- if(p->flags & p_echo) ttputc(ch);
- s_pos = x_pos;
- x_pos++;
- cp++;
- break;
- case '\b':
- if(cp > p->line) {
- cp--;
- if(p->flags & p_echo) ttputs("\b \b");
- x_pos--;
- /* If they wipe out a space we've got to find the previous one */
- if(*cp == ' ') {
- r = cp-1;
- while(r > p->line) {
- if(*r == ' ') break;
- r--;
- }
- s_pos = r - p->line;
- }
-
- }
- break;
-
- case '\n':
- if(cp is p->line) {
- *cp = '\0';
- return(1);
- }
- break;
- }
- #ifdef OLD_CODE
- switch(*cp) {
- default:
- if (p->flags & p_echo) outchar(*cp);
- cp++;
- break;
- case '\b':
- if(cp > p->line) {
- cp--;
- if(p->flags & p_echo)outstr("\b \b");
- }
- break;
-
- case '\n':
- if(cp is p->line) {
- *cp = '\0';
- return(1);
- }
- break;
- case '\0' : /* Ignore most ctl char */
- case ctl_c: /* Ignore most ctl char */
- case ctl_v: /* Ignore most ctl char */
- case '\033':
- break;
- }
- #endif
- return(0);
- }
-
- /* replace waitcmd from mbtnc to reduce busy waits */
- /* NOT NEEDED in SYSOP */
- waitcmd(x)
- int x;
- {
- }
-
-
-
- /* Replace the pause routine so that it can be used with TNC as well
- as the console. If routine times out after 2 minutes then it will
- return 'Q'.
- The test for optflags[2] allows the SYSOP to specify whether the system
- will pause after 20 lines of output to the user.
- */
- pause()
- {
-
- register char ch,*q;
- ULONG class,waitbits;
- USHORT code;
- if(arexx_port)return(' ');
- if (port->user->state & u_pause) return ' ';
- /* If remote user has interrupted, then return a 'Q' anyway */
- if(!optflags[2] && ((port->mode != local) || (pt_flag)))return(' ');
-
- q = &tmpstr[0];
- prtx(pausemsg);
- if(port->mode != local)outchar('\n');
- settimer(120); /* set timeout timer */
- waitbits = windbit | timerbit | keybit;
- while(1) {
- getbits = Wait(waitbits);
- if(windbit & getbits) {
- while(NewMessage =
- (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = toupper(ichar);
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- outchar('\n');
- return(ch);
- }
- /* check for timeout */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- return('Q');
- }
- }
- }
-
- /* Null routines from the mblog.c file.
- SYSOP does not do any logging whatever (there's also a small fix in
- mbinit.c to turn off all the logging flags).
- It also does no monitoring.
- */
- /* Define the length of a heard item. It is easier to do this and have
- mbinit allocate a very small heard list than to have another version
- of mbinit just for one small change.
- */
- char *lgfile = 0,*monfile = 0,*hrdfile = 0;
- int hrdmax = 1;
- char fbb_direction;
- /* Dummy fbb forwarding */
- char *mbvers,*fbbvers;
- fbbfwd()
- {
- }
-